﻿using System;
using Ascend.Runtime.Core;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Zove.Runtime.Core;

namespace Zove.Runtime.Test.Ascend
{
    /// <summary>
    /// Summary description for AscendTests
    /// </summary>
    [TestClass]
    public class AscendTests
    {
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext { get; set; }

        #region Additional test attributes

        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //

        #endregion

        [TestMethod]
        public void TestRun()
        {
            const string source =
                @"MODEL Test
a IS_A factor;
b IS_A factor;

a = b*2;
METHODS
METHOD on_load
END on_load
END Test";

            const string source2 = @"MODEL thermalequilibrium;
	T_1 IS_A temperature;
	T_2 IS_A temperature;
	m_1, m_2 IS_A mass;
	C_p IS_A specific_heat_capacity;
	h IS_A heat_transfer_coefficient;
	A IS_A area;

	Q IS_A energy_rate;
	Q = h*A*(T_1 - T_2);
	m_1*C_p*dT1dt = 0-Q;
	m_2*C_p*dT2dt = 0+Q;
	
	dT1dt IS_A temperature_rate;
	dT2dt IS_A temperature_rate;

	t IS_A time;
METHODS
METHOD on_load;
	FIX C_p, h, A, m_1, m_2, T_1, T_2;
	A := 1 {m^2};
	h := 10 {W/m^2/K};
	C_p := 4.2 {kJ/kg/K};
	m_1 := 10 {kg};
	m_2 := 10 {kg};

	T_1 := 500 {K};
	T_2 := 290 {K};

	t.ode_type := 1;

	T_1.ode_id := 1;
	dT1dt.ode_id := 1;
	T_1.ode_type := 1;
	dT1dt.ode_type := 2;

	T_2.ode_id := 2;
	dT2dt.ode_id := 2;
	T_2.ode_type := 1;
	dT2dt.ode_type := 2;

	Q.obs_id := 2;
	T_1.obs_id := 3;
	T_2.obs_id := 4;
	
END on_load;

END thermalequilibrium;";
            var languageNature = new AscendLanguageNature();
            languageNature.ClassFinder.AddClassPath(@"C:\Program Files\ASCEND\models");

            ZoomClass c = languageNature.ClassLoader.LoadFromSource(source);
            Console.WriteLine(c);

            var model = new AscendModel(source2);
            model.Run();

            c = languageNature.ClassLoader.LoadFromSource(source2);
            Console.WriteLine(c);

            model = new AscendModel(source2);

            model.Run();
        }

        [TestMethod]
        public void TestIndex()
        {
            var finder = new AscendClassFinder();

            finder.Scan(@"C:\Program Files\ASCEND\models\ben");

            Console.WriteLine(finder.Index.Count);
            foreach (string model in finder.Index.Keys)
            {
                Console.WriteLine(model);
            }
        }

        [TestMethod]
        public void TestComment()
        {
            var lexer =
                new AscendLexer(
                    @"
(* This MODEL deals with the backend and the c3 splitter
 * IN particular. There are only 3 components IN this MODEL.
 *)
   
REQUIRE system;
");

            lexer.NextToken();

            Assert.AreEqual(
                @"
(* This MODEL deals with the backend and the c3 splitter
 * IN particular. There are only 3 components IN this MODEL.
 *)",
                lexer.LastComment);
        }

        [TestMethod]
        public void TestVaporModel()
        {
            string source =
                @"

MODEL Vapor;

    P1S, P2S, P, T, x1, x2, y1, y2 IS_A factor;

    ln(P1S) = 14.2724 - 2945.47/(T + 224.0);

    ln(P2S) = 14.2043 - 2972.64/(T + 209.0);

    x1 + x2 = 1.0;
    y1 + y2 = 1.0;

    x1*P1S = y1*P;
    x2*P2S = y2*P;

METHODS
    METHOD parta;
        FIX T; FIX x1;

        x1 := 0.6;
        T := 75.0;
    END parta;

    METHOD partb;
        FIX P; FIX x1;

        x1 := 0.1;
        P := 70.0;
            T := 300.0;

    END partb;
    METHOD doparta;
            RUN ClearAll;

        RUN parta;
    END doparta;
    METHOD dopartb;

            RUN ClearAll;
        RUN partb;
    END dopartb;

END example101;
";

            var languageNature = new AscendLanguageNature();
            RuntimeModel model = languageNature.ModelLoader.LoadBySource(source);

            Console.WriteLine(model.ToString());
        }
    }
}